package osi;

import cn.hutool.core.date.LocalDateTimeUtil;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.NetworkIF;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OSProcess;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;

import java.security.Timestamp;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 黄乾坤
 * @create 2022-08-29 10:48
 */
public class OshiUtil {

    private static Runtime r = Runtime.getRuntime();

    public static void main(String[] args){
        SystemInfo systemInfo = new SystemInfo();
        HardwareAbstractionLayer hal = systemInfo.getHardware();
        memory(hal.getMemory());
        cpu(hal.getProcessor());
        os(systemInfo.getOperatingSystem());

    }

    /**
     * 获取内存使用信息
     *
     * @return
     */
    public static void memory(GlobalMemory memory) {
        long total = memory.getTotal() / 1024L / 1024L;
        long free = memory.getAvailable() / 1024L / 1024L;
        double usePer = (double) (total - free) / (double) total;
        double used = FormatUtil.formatDouble(usePer * 100, 2);
        System.out.println("total:" + total);
        System.out.println("free:" + free);
        System.out.println("used percent:" + used + "%");
    }


    /**
     * 获取cpu使用率、cpi核心数、cpu型号
     *
     * @return
     */
    public static void cpu(CentralProcessor processor) {
        System.out.println("cpu core:" + processor.getLogicalProcessorCount());
        String cpuInfo = processor.toString();
        if (cpuInfo.indexOf("\n") > 0) {
            cpuInfo = cpuInfo.substring(0, cpuInfo.indexOf("\n"));
        }
        System.out.println("cpu info:" + cpuInfo);

        long[] prevTicks = processor.getSystemCpuLoadTicks();
        // Wait a second...
        Util.sleep(1000);
        double cpuPercent = FormatUtil.formatDouble(processor.getSystemCpuLoadBetweenTicks(prevTicks) * 100, 1);
        System.out.println("cpu percent:" + cpuPercent);
    }

    /**
     * 获取操作系统信息
     *
     * @return
     */
    public static void os(OperatingSystem os) {
        System.out.println("os version:" + os.toString());
    }

    /**
     * 获取磁盘使用信息
     *
     * @throws Exception
     */
    public static void file(FileSystem fileSystem) throws Exception {
        System.out.println("current time: " + LocalDateTimeUtil.now());
        List<OSFileStore> fsArray = fileSystem.getFileStores();
        for (int i = 0; i < fsArray.size(); i++) {
            OSFileStore fs = fsArray.get(i);
            long usable = fs.getUsableSpace();
            long total = fs.getTotalSpace();

            System.out.println("\tdisk" + i + ":" + fs.getName());
            String used = ((total - usable) / 1024 / 1024 / 1024) + "G";
            System.out.println("\tused:" + used);
            String avail = (usable / 1024 / 1024 / 1024) + "G";
            System.out.println("\tavail:" + avail);
            String totalSize = (total / 1024 / 1024 / 1024) + "G";
            System.out.println("\ttotal:" + totalSize);

            double usedSize = (total - usable);
            double usePercent = 0;
            if (total > 0) {
                usePercent = FormatUtil.formatDouble(usedSize / total * 100D, 2);
            }
            System.out.println("\tused percent:" + usePercent + "%");
            System.out.println("-----------------------------------------------");
        }
    }

    /**
     * 获取系统负载
     *
     * @return
     */
    public static void getLoadState(SystemInfo systemInfo, CentralProcessor processor) throws Exception {
        if (systemInfo == null) {
        }
        if (systemInfo.getOperatingSystem().toString().indexOf("Microsoft") > -1) {
            //windows系统不支持负载指标
            System.out.println("load: windows not support");
            return;
        }
        double[] loadAverage = processor.getSystemLoadAverage(3);
        System.out.println("1 minute:" + loadAverage[0]);
        System.out.println("5 minute:" + loadAverage[1]);
        System.out.println("15 minute:" + loadAverage[2]);
    }


    /**
     * 获取网络带宽
     *
     * @param hal
     * @return
     * @throws Exception
     */
    public static void net(HardwareAbstractionLayer hal) throws Exception {
        long rxBytesBegin = 0;
        long txBytesBegin = 0;
        long rxPacketsBegin = 0;
        long txPacketsBegin = 0;
        long rxBytesEnd = 0;
        long txBytesEnd = 0;
        long rxPacketsEnd = 0;
        long txPacketsEnd = 0;
        List<NetworkIF> listBegin = hal.getNetworkIFs();
        for (NetworkIF net : listBegin) {
            rxBytesBegin += net.getBytesRecv();
            txBytesBegin += net.getBytesSent();
            rxPacketsBegin += net.getPacketsRecv();
            txPacketsBegin += net.getPacketsSent();
        }

        //暂停3秒
        Thread.sleep(5000);
        List<NetworkIF> listEnd = hal.getNetworkIFs();
        for (NetworkIF net : listEnd) {
            rxBytesEnd += net.getBytesRecv();
            txBytesEnd += net.getBytesSent();
            rxPacketsEnd += net.getPacketsRecv();
            txPacketsEnd += net.getPacketsSent();
        }

        long rxBytesAvg = (rxBytesEnd - rxBytesBegin) / 3 / 1024;
        long txBytesAvg = (txBytesEnd - txBytesBegin) / 3 / 1024;
        long rxPacketsAvg = (rxPacketsEnd - rxPacketsBegin) / 3 / 1024;
        long txPacketsAvg = (txPacketsEnd - txPacketsBegin) / 3 / 1024;
        System.out.println("received per second:" + rxBytesAvg + " KB/s");//每秒接收的kb数
        System.out.println("received per second:" + rxPacketsAvg + " rxpck/s");//每秒接收的数据包
        System.out.println("sent per second:" + txBytesAvg + " KB/s");//每秒发送的kb数
        System.out.println("sent per second:" + txPacketsAvg + " txpck/s");//每秒发送的数据包
    }
}
